﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EzyThirdLogic.ExtensionMethods;

namespace EzyThirdLogic
{
    public class RelationsBuilder
    {
        private string[][] fdSet;

        public RelationsBuilder(string[][] input)
        {
            fdSet = input;
        }

        public FunctionalDependencySetCollection DisplayRelationStep6()
        {
            //var ll = new LinkedList<string>();
            var f = new FunctionalDependencySet(fdSet, fdSet.Length);
            var p = new Partitioner();
            var bigset = p.Partition(f);
            var m = new Merger();
            bigset = m.Merge(bigset, f);
            bigset = RegroupStep6(f, bigset, m.GetJ());
            return bigset;
        }

        public string ToStringStep6()
        {
            string res = "";
            var ll = new LinkedList<string>();
            var f = new FunctionalDependencySet(fdSet, fdSet.Length);
            var p = new Partitioner();
            var bigset = p.Partition(f);
            var m = new Merger();
            bigset = m.Merge(bigset, f);
            bigset = RegroupStep6(f, bigset, m.GetJ());
            ll = bigset.FDSetCollectionToRelation();
            for (int i = 0; i < ll.Count; i++)
            {
                res += ll.ElementAt<string>(i);
                res += "\n";
            }
            res += "\n";
            return res;
        }

        public FunctionalDependencySetCollection RegroupStep6(FunctionalDependencySet fdSet, FunctionalDependencySetCollection fdSetCollection, List<FunctionalDependencySet> setJ)
        {
            for (int i = 0; i < setJ.Count; i++)
            {
                bool flag = false;
                var closureJ = SynthesizingAlgorithm.AttributeClosure(fdSet, setJ[i].FDSet.ElementAt<FunctionalDependency>(0).BitDeterminant);
                fdSetCollection.FDSetCollection.Remove(setJ[i]);

                foreach (var fds in fdSetCollection.FDSetCollection)
                {
                    foreach (var fd in fds.FDSet)
                    {
                        var LHS = fd.BitDeterminant;
                        var closureLHS = SynthesizingAlgorithm.AttributeClosure(fdSet, LHS);
                        if (closureJ.IsEquals(closureLHS))
                        {
                            flag = true;
                        }
                        break;
                    }
                    if (flag)
                    {
                        fdSetCollection.FDSetCollection.Remove(fds);
                        fdSetCollection.FDSetCollection.Add(fds.MergeFunctionalDependencySets(fds, setJ[i]));
                        break;
                    }
                }
                if (!flag)
                {
                    fdSetCollection.FDSetCollection.Add(setJ[i]);
                }
            }
            return fdSetCollection;
        }
    }
}
